package com.aaa.vegetablemarketexpress.util;

import com.aaa.vegetablemarketexpress.entity.OperLog;
import com.aaa.vegetablemarketexpress.entity.User;
import com.aaa.vegetablemarketexpress.service.OperateService;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.AfterThrowing;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.util.Date;

/**
 * @FileName: RecordLogUtil
 * @Description:统一记录操作日志的工具类（切面的实现类）
 * @Author: HQH
 * @CreateTime: 2025/9/17 15:01
 * @Version: 1.0.0
 */
@Component //IOC 把当前工具类交给spring容器管理
@Aspect  //标识当前类是切面的实现类
public class RecordLogOperUtil {
    @Resource
    private OperateService operateService;

    @Resource
    private HttpSession session;

    @Resource
    private HttpServletRequest request;
    /**
     * 编写一个切入点方法 方法可以不写任何代码 让日志记录方法和业务方法产生联系的一个方法
     * */
//    @Pointcut("execution(* com.aaa.vegetablemarketexpress.service.impl.*.add(..)) ||" +
//            "execution(* com.aaa.vegetablemarketexpress.service.impl.*.update(..))||"+
//            "execution(* com.aaa.vegetablemarketexpress.service.impl.*.delete*(..))"
//
//    @Pointcut("execution(* com.aaa.vegetablemarketexpress.service.impl.*.add(..)) ||" +
//          "execution(* com.aaa.vegetablemarketexpress.service.impl.*.insert*(..)) ||" +  // 新增：匹配insert开头的方法
//          "execution(* com.aaa.vegetablemarketexpress.service.impl.*.update(..))||"+
//          "execution(* com.aaa.vegetablemarketexpress.service.impl.*.delete*(..))"
//)
    @Pointcut("(execution(* com.aaa.vegetablemarketexpress.service.impl.*.add(..)) ||" +
            "execution(* com.aaa.vegetablemarketexpress.service.impl.*.insert*(..)) ||" +
            "execution(* com.aaa.vegetablemarketexpress.service.impl.*.update(..))||"+
            "execution(* com.aaa.vegetablemarketexpress.service.impl.*.delete*(..))) && " +
            "!within(com.aaa.vegetablemarketexpress.service.impl.OperateLogServiceImpl)" // 排除日志服务类
    )
    //配置切入点
    //execution() 放入真正的切入点表达式
    public void cutPoint(){

    }
    @AfterReturning(pointcut = "cutPoint()")//表示当前记录日志功能是在真正业务方法执行After
    public void recordOperLog(JoinPoint joinPoint){
        //joinPoint连接点 spring提供的一个类，可以获取连接点信息
        //获取正在执行的方法名称
        String executeMethodName = joinPoint.getSignature().getName();
        System.out.println("正在执行方法名称为："+executeMethodName);
        System.out.println("模拟--------记录日志功能---11---");
        //实例化添加对象
        OperLog operLog = new OperLog();
        //获取到目标对象，根据目标对象判断属于什么模块
        operLog.setTitle("系统管理模块");
        //定义业务类型
        int businessType = 1;
        if(executeMethodName.contains("update")){
            businessType = 2;
        }else if(executeMethodName.contains("delete")){
            businessType = 3;
        }
        //业务类型（0其他1新增2修改3删除）
        operLog.setBusinessType(businessType);
        //获取目标对象
        String targetName=joinPoint.getTarget().getClass().getName();
        //方法名称 （那个类中的那个方法）
        operLog.setMethod(targetName+"."+executeMethodName);
        //请求方式
        operLog.setRequestMethod(request.getMethod());
        //操作类别
        operLog.setOperatorType(1);
        //获取当前登录的用户信息
        User user = (User) session.getAttribute("userInfo");
        if(user!=null){
            //操作人员（userName）
            operLog.setOperName(user.getUserName());
            //部门信息
            operLog.setOperName(user.getDeptId()+"");
        }
        //operLog.setDeptName(user.getDept().toString());
        //operLog.setDeptName("开发部");
        //使用httpservletrequest获取当前请求的url
        String requestURL = request.getRequestURI().toString();
        //请求的url
        operLog.setOperUrl(requestURL);
        //请求Ip地址
        String remoteAddr = request.getRemoteAddr();
        System.out.println("请求的IP为："+remoteAddr);
        operLog.setOperIp(remoteAddr);
        //操作地点
        operLog.setOperLocation("郑州");
        //使用JoinPoint对象获取所有参数
        Object[] argArray= joinPoint.getArgs();
        //判断数组
        if(argArray!=null&&argArray.length>0){
            String firstArgName = argArray[0].getClass().getName();
            //请求参数
            operLog.setOperParam(firstArgName);
        }
        //返回参数
        operLog.setJsonResult(joinPoint.getSignature().getName());
        //状态（0正常1不正常）
        operLog.setStatus(0);
        //设置属性
        //设置日志操作时间 获取当前时间
        operLog.setOperTime(new Date());
        operateService.add(operLog);
    }
    /**
     *异常通知：在执行业务方法中出现异常执行的方法  记录日志功能
     * */
    @AfterThrowing(pointcut = "cutPoint()",throwing = "e")//表示当前记录日志功能是在真正业务方法执行After
    public void recordErrorOperLog(JoinPoint joinPoint,Exception e){
        //joinPoint连接点 spring提供的一个类，可以获取连接点信息
        //获取正在执行的方法名称
        String executeMethodName = joinPoint.getSignature().getName();
        System.out.println("正在执行方法名称为："+executeMethodName);
        System.out.println("模拟--------记录日志功能---11---");
        //实例化添加对象
        OperLog operLog = new OperLog();
        //获取到目标对象，根据目标对象判断属于什么模块
        operLog.setTitle("系统管理模块");
        //定义业务类型
        int businessType = 1;
        if(executeMethodName.contains("update")){
            businessType = 2;
        }else if(executeMethodName.contains("delete")){
            businessType = 3;
        }
        //业务类型（0其他1新增2修改3删除）
        operLog.setBusinessType(businessType);
        //获取目标对象
        String targetName=joinPoint.getTarget().getClass().getName();
        //方法名称 （那个类中的那个方法）
        operLog.setMethod(targetName+"."+executeMethodName);
        //请求方式
        operLog.setRequestMethod(request.getMethod());
        //操作类别
        operLog.setOperatorType(1);
        //获取当前登录的用户信息
        User user = (User) session.getAttribute("userInfo");
        if(user!=null){
            //操作人员（userName）
            operLog.setOperName(user.getUserName());
            //部门信息
            operLog.setOperName(user.getDeptId()+"");
        }
        //operLog.setDeptName(user.getDept().toString());
        //operLog.setDeptName("开发部");
        //使用httpservletrequest获取当前请求的url
        String requestURL = request.getRequestURI().toString();
        //请求的url
        operLog.setOperUrl(requestURL);
        //请求Ip地址
        String remoteAddr = request.getRemoteAddr();
        System.out.println("请求的IP为："+remoteAddr);
        operLog.setOperIp(remoteAddr);
        //操作地点
        operLog.setOperLocation("郑州");
        //使用JoinPoint对象获取所有参数
        Object[] argArray= joinPoint.getArgs();
        //判断数组
        if(argArray!=null&&argArray.length>0){
            String firstArgName = argArray[0].getClass().getName();
            //请求参数
            operLog.setOperParam(firstArgName);
        }
        //返回参数
        operLog.setJsonResult(joinPoint.getSignature().getName());
        //状态（0正常1不正常）
        operLog.setStatus(1);
        //异常信息
        operLog.setErrorMsg(e.getClass().getName());
        //设置属性
        //设置日志操作时间 获取当前时间
        operLog.setOperTime(new Date());
        operateService.add(operLog);
    }
}